package com.helei.web.component;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.gson.Gson;
import com.helei.common.api.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.validation.constraints.NotNull;

/**
 * 用作接口返回的各种类型统一转换为Result类型的包装对象
 *
 * @author hl
 * @date 2021-07-14 00:19:58
 */
@Slf4j
@RestControllerAdvice(basePackages = {"com.helei.web.controller"}) // 这里要加上需要扫描的包
public class ResponseControllerAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, @NotNull Class<? extends HttpMessageConverter<?>> aClass) {
        //System.out.println("supports:" + returnType.getParameterType().getName() + "-" + Result.class.getName());
        // 如果接口返回的类型本身就是Result那就没有必要进行额外的操作，返回false
//        return !returnType.getParameterType().equals(Result.class) || !returnType.getParameterType().equals(CommonResult.class) || !returnType.getParameterType().equals(ResponseEntity.class);
        return !returnType.getParameterType().equals(Result.class) && !returnType.getParameterType().equals(ResponseEntity.class) && !returnType.getParameterType().equals(ByteArrayResource.class);
    }

    @Override
    public Object beforeBodyWrite(Object data, @NotNull MethodParameter returnType, @NotNull MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest request, ServerHttpResponse response) {
        if ((data instanceof Result) || (data instanceof ResponseEntity) || (data instanceof ByteArrayResource)) {
            return data;
        }

        // String类型不能直接包装，所以要进行些特别的处理
//        if (returnType.getGenericParameterType().equals(String.class)) {
//            ObjectMapper objectMapper = new ObjectMapper();
//            try {
//                // 将数据包装在Result里后，再转换为json字符串响应给前端
//                return objectMapper.writeValueAsString(Result.ok(data));
//            } catch (JsonProcessingException e) {
//                throw new ApiException("返回String类型错误");
//            }
//        }

        //System.out.println(data.getClass().getName());

        if (data instanceof String) {
            return new Gson().toJson(Result.ok(data));
        } else if (data instanceof IPage) {
            return Result.okPage((IPage) data);
        }
        // 将原本的数据包装在Result里
        return Result.ok(data);
    }
}